/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.core.commands;

import java.util.List;

import org.eclipse.gef.commands.Command;

import com.cea.papyrus.diagraminterchange2.di2.GraphNode;



/**
 * 
 */
public class FeatureMoveChildCommand extends Command {

	/**
	 * 
	 */
	private GraphNode child;
	
	/**
	 * 
	 */
	private GraphNode after;
	
	/**
	 * 
	 */
	private List list;
	
	/**
	 * 
	 */
	private int oldPos;

	/**
	 * Returns the <code>Command</code> to move the specified
	 * child before the given reference <code>EditPart</code>. If the
	 * reference is <code>null</code>, the child should be moved in front
	 * of all children.
	 * <P>
	 * A move is a change in the order of the children, which indirectly
	 * causes a change in location on the screen.
	 * 
	 * @param child the child being moved
	 * @param featureList 
	 * @param after <code>null</code> or the EditPart that should be after
	 * (or to the right of) the child being moved
	 * 
	 * @return a Command to move the child
	 */
	public FeatureMoveChildCommand(GraphNode featureList, GraphNode child, GraphNode after ) {
		this.list = featureList.getContained();
		this.child = child;
		this.after = after;
	}

	/**
	 * Can execute if all the necessary information has been provided.
	 * 
	 * @return 
	 * 
	 * @see org.eclipse.gef.commands.Command#canExecute()
	 */
	@Override
	public boolean canExecute() {
		return list.indexOf(child) >= 0 ;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gef.commands.Command#execute()
	 */
	/**
	 * 
	 */
	@Override
	public void execute() {
		

		redo();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gef.commands.Command#redo()
	 */
	/**
	 * 
	 */
	@Override
	public void redo() {
		// Compute the index here because Command can be called twice.
		int atPos = list.indexOf(after);
		int childPos = list.indexOf(child);
		oldPos = childPos;
		
		
		if( (childPos == atPos) || (childPos+1 == atPos) ) {
			return;
		}
		
		if( after == null )
		{ // Add at end
			if( childPos == list.size()-1 )
			{ // Already at end, skip
				return;
			}
			list.remove(childPos);
		    list.add(child);
		}
		else 
		{ 
			list.remove(childPos);
			if (atPos > childPos )
			{
		      // Position has changed because of the remove		
			  list.add(atPos-1, child);
			}
			else // atPos < childPos
			{ // Position hasn't changed
			list.add(atPos, child);
			}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gef.commands.Command#undo()
	 */
	/**
	 * 
	 */
	@Override
	public void undo() {
		int atPos = list.indexOf(after);
		int childPos = list.indexOf(child);

		if( childPos == oldPos ) {
			return;
		}
		
		list.remove(atPos);
		list.add(oldPos, child);
	}
	
}
